import 'dart:convert';
import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:full_display/page/montage/montage_provider.dart';
import 'package:full_display/unit/toast/toast_util.dart';
import 'package:provider/provider.dart';

class SocketUDPUtils {
  final int _serverPort = 28990; //本机服务器端口，监听消息
  // final int _destinationPort = 28990; //发送目的地端口，发送消息
  late RawDatagramSocket _bindSocket;
  late RawDatagramSocket _rawSocket;
  static var mStream;
  var _montageProvider = MontageProvider();
  SocketUDPUtils._internal();
  static final SocketUDPUtils _socketUDPUtils = SocketUDPUtils._internal();
  factory SocketUDPUtils() {
    return _socketUDPUtils;
  }

  // socket事件
  void onSocketData(RawSocketEvent e) {
    switch (e) {
      //read 接收事件
      case RawSocketEvent.read:
        {
          Datagram? dg = _bindSocket.receive();
          if (dg != null) {
            // showToast(
            // "接收数据：\n data:${utf8.decode(dg.data)} \n ip:${dg.address.toString()} \n port:${dg.port} \n 数据长度:${dg.data.lengthInBytes}");
            print(
                '----[socket utils]----收到来自${dg.address.toString()}:${dg.port}的数据：${dg.data.lengthInBytes}字节数据 ');
            revicedata(utf8.decode(dg.data), dg);
          }
        }
        break;
      //write 发送事件
      case RawSocketEvent.write:
        {
          print('RawSocketEvent.write');
        }
        break;
      case RawSocketEvent.readClosed:
        {
          print('RawSocketEvent.readClosed');
        }
        break;
      case RawSocketEvent.closed:
        {
          print('RawSocketEvent.closed');
        }
        break;
    }
  }

  // socket关闭
  void onSocketDone() {
    _bindSocket.close();
    print('----[socket utils]----socket关闭');
  }

  // socket错误
  void onSocketError(Object error) {
    print('----[socket utils]----socket出现错误，error=${error.toString()}');
  }

  void waitUDPMsg() async {
    mStream = _bindSocket.asBroadcastStream();

    /// 监听套接字事件
    mStream.listen(onSocketData, onError: onSocketError, onDone: onSocketDone);
  }

  void initALlUDP() async {
    InternetAddress addressIpv4 = InternetAddress.anyIPv4;
    _rawSocket = await RawDatagramSocket.bind(addressIpv4, 0);
    _bindSocket = await RawDatagramSocket.bind(addressIpv4, _serverPort);
    _bindSocket.readEventsEnabled = true;
  }

  void initData(BuildContext context) async {
    _montageProvider = context.watch<MontageProvider>();
  }

  //全局广播
  void sendUDPMsg(String msg) {
    if (_rawSocket != null) {
      InternetAddress address =
          InternetAddress('255.255.255.255', type: InternetAddressType.IPv4);
      _rawSocket.broadcastEnabled = true;
      // print('----[send data]----发送至${utf8.encode(json.encode(msg))}');
      _rawSocket.send(msg.codeUnits, address, _serverPort);
      print('----[socket utils]----发送至$address-----:$_serverPort的数据：内容:${msg}');
    }
    // rawSocket.close();
  }

  //单个IP发送
  void sendUDPMsgToIp(InternetAddress address, int port, String msg) async {
    InternetAddress addressIpv4 = InternetAddress.anyIPv4;
    RawDatagramSocket rawSocket =
        await RawDatagramSocket.bind(addressIpv4, _serverPort);
    // rawSocket.broadcastEnabled = true;
    rawSocket.send(msg.codeUnits, address, _serverPort);
    print(
        '----[IP socket utils]----发送至$address----bind:$addressIpv4-----:$port的数据：内容:${msg}');
    rawSocket.close();
  }

  void revicedata(String msg, Datagram dg) {
    print("msg------------->${msg}");
    InternetAddress dgAddress = InternetAddress(dg.address.address);
    int dgPort = dg.port;
    if (msg.indexOf("SSDP") == 0) //是SSDP指令
    {
      String endString = msg.replaceAll("SSDP:", "");
      if (endString.contains("JOINED:")) {
        endString = endString.replaceAll("JOINED:", "");
        print("endString------------->${endString}");
        _montageProvider.deviceList = endString.split(':');
        print("sn------------->${_montageProvider.deviceList}");
        if (endString.contains("LOOP")) {
        } else if (endString.contains("SINGLE")) {}
        if (endString.contains("RANDOM")) {}
      } else if (endString != "BROADCAST" && endString.length == 12) {
        //设备第一次启动后
        print("endString1111------------->${endString}");
        sendUDPMsgToIp(dgAddress, dgPort, "SSDP:OK");
        // Thread.Sleep(2);
        sendUDPMsgToIp(dgAddress, dgPort, "JOIN");
        // downLoading = false;
      } else if (endString.contains("BROADCAST2")) {
        //其它客户端有打开
      }
    } else if (msg.indexOf("JOIN:") == 0) {
      String endString = msg.replaceAll("JOIN:", "");
      // Console.WriteLine(str);
      if (endString.contains("OK")) {
        print("加入拼接成功!");
      }
    } else if (msg.indexOf("DOWNLOAD:") == 0) {
      print(
          "Receive Download:${dg.address.toString()}---:${msg}---:${DateTime.now()}"); //toString().substring(0,19)
      String endString = msg.replaceAll("DOWNLOAD:", "");

      // downLoading = false;
      if (endString == "START") {
        // downLoading = true;
        //Console.WriteLine("表示客户端回复，我已经开始下载了!");
        // UpdatequeueBroad(iep.Address.ToString(), DownloadState.DownloadStart);
      } else if (endString == "SUCCESS") {
        // downLoading = false;
        // Console.WriteLine("表示客户端告知服务器下载完成!" + "send DOWNLOAD:SUCCESS:OK");
        // UpdatequeueBroad(iep.Address.ToString(), DownloadState.DownloadSucess);

        sendUDPMsgToIp(dgAddress, dgPort, "DOWNLOAD:SUCCESS:OK");
      } else if (endString == "FAILED") {
        // downLoading = false;
        // Console.WriteLine("表示客户端告知服务器下载失败!" + "send DOWNLOAD:FAILED:OK");

        sendUDPMsgToIp(dgAddress, dgPort, "DOWNLOAD:FAILED:OK");
      } else if (endString == "RUNNING") {
        //Console.WriteLine("表示客户端告知服务器下载失败!");
        // UpdatequeueBroad(iep.Address.ToString(), DownloadState.DownloadOptimised);
        //  Console.WriteLine("表示客户端正在下载中,暂时不处理,再等待!");
      } else if (endString == "RESET:START") {
        //  Console.WriteLine("表示客户端回复，我已经开始下载了,RESET!");
        // var dev = SplitMain.wsDc.FirstOrDefault(x => x.Fs_Broadcast.Ip == iep.Address.ToString());
        // if (dev != null)
        // {
        //     dev.Fs_Broadcast.IsReadyDown = true;
        // }
      } else if (endString == "OPTIMISE:FINISHED" || endString == "OPTIMISED") {
        print("表示客户端告知服务器解码完成! --- send DOWNLOAD:OPTIMISED:OK");
        // UpdatequeueBroad(iep.Address.ToString(), DownloadState.DownloadOptimised);

        sendUDPMsgToIp(dgAddress, dgPort, "DOWNLOAD:OPTIMISED:OK");
      } else {
        print("好奇怪的指令${msg}");
      }
    } else if (msg.indexOf("REPORT:") == 0) {
      String endString = msg.replaceAll("REPORT:", "");
      if (endString.indexOf("ALARM") == 0) {
        endString = endString.replaceAll("ALARM", "");
        print("=====>${endString}");
        List timingSwitch = endString.split(':');
        // SplitMain.CreateInstrance().listTimingSwitch = new List<Shared.Model.split.splice_timingswitch>();
        // for (int k = 0; k < timingSwitch.Length; k += 3)
        // {
        //     SplitMain.CreateInstrance().listTimingSwitch.Add(new Shared.Model.split.splice_timingswitch
        //     {
        //         index = Convert.ToInt32(timingSwitch[k]),
        //         startSeconds = Convert.ToInt32(timingSwitch[k + 1]),
        //         endSeconds = Convert.ToInt32(timingSwitch[k + 2])
        //      });
        // }
      }
    }
  }
}
